package me.minecraft.woodenman.runnable;

import lombok.Getter;
import me.minecraft.woodenman.GameStage;
import me.minecraft.woodenman.WoodenMan;
import me.minecraft.woodenman.config.Language;
import org.bukkit.GameMode;
import org.bukkit.Location;
import org.bukkit.World;
import org.bukkit.entity.*;
import org.bukkit.scheduler.BukkitRunnable;

import java.util.HashMap;
import java.util.HashSet;
import java.util.Map;
import java.util.Set;

/**
 * @author langle__
 * @version 1.0
 */
@Getter
public class GameTask extends BukkitRunnable {

    private final Set<Player> players = new HashSet<>();
    private final Set<Player> movePlayers = new HashSet<>();

    private final Map<Player, GameMode> playerGameMode = new HashMap<>();
    private final Map<Player, Location> playerLocation = new HashMap<>();

    private GameStage gameStage = GameStage.START;
    private boolean running = false;
    private boolean woodenManLookingBack = false;
    private boolean playerMove = true;
    private int tick = -1;
    private int gameTime = 0;
    private int second = 5;

    private Zombie woodenMan;

    private int tempReactionTime;

    public GameTask() {
    }

    @Override
    public void run() {
        if (tick >= 20) {
            gameTime++;
            tick = 0;
        }
        tick++;
        if (gameStage == GameStage.START) {
            players.forEach(player -> playerGameMode.put(player, player.getGameMode()));
            players.forEach(player -> playerLocation.put(player, player.getLocation()));
            players.forEach(player -> player.teleport(getRandomLocationAround(WoodenMan.playerLocation, 3)));
            players.forEach(player -> player.setGameMode(GameMode.ADVENTURE));
            World world = WoodenMan.woodenManLocation.getWorld();
            if (world == null) return;
            woodenMan = (Zombie) world.spawnEntity(WoodenMan.woodenManLocation, EntityType.ZOMBIE);
            woodenMan.setCustomName(Language.WOODENMAN_NAME);
            woodenMan.setCustomNameVisible(true);
            woodenMan.setInvulnerable(true);
            woodenMan.setAI(false); // 禁用 AI
            woodenMan.setBaby(false); // 确保不是小僵尸
            woodenMan.setRemoveWhenFarAway(false); // 防止自然刷新
            gameStage = GameStage.WAITING;
            playerMove = false;
        } else if (gameStage == GameStage.WAITING) {
            if (tick >= 20) {
                second--;
                for (Player p : players) {
                    p.sendMessage(String.format(Language.COUNTDOWN, second));
                }
            }
            if (second == 0) {
                players.forEach(player -> player.sendMessage(Language.GAME_STARTED));
                gameStage = GameStage.PLAYING;
                playerMove = true;
            }
        } else if (gameStage == GameStage.PLAYING) {
            if (woodenManLookingBack) {
                if (tempReactionTime >= gameTime) {
                    return;
                }
                for (Player player : movePlayers) {
                    player.sendMessage(Language.PLAYER_MOVED);
                    removePlayer(player);
                }
                movePlayers.clear();
                if (gameTime >= tempReactionTime + 5) {
                    players.forEach(player -> player.sendTitle(Language.PREFIX, Language.PLAYER_CAN_MOVE, 10, 30, 10));
                    woodenManLookingBack = false;
                }
            } else {
                if (tick >= 20 && gameTime >= 3) {
                    if (Math.random() < 0.5) {
                        woodenManLookingBack = true;
                        tempReactionTime = gameTime + 1;
                        players.forEach(player -> player.sendTitle(Language.PREFIX, Language.WOODENMAN_LOOKING_BACK, 10, 30, 10));
                    }
                }
            }
            if (players.isEmpty()) {
                gameStage = GameStage.END;
            }
        } else if (gameStage == GameStage.END) {
            players.forEach(player -> player.sendMessage(Language.GAME_ENDED));
            this.stop();
        }
    }

    public void start() {
        if (WoodenMan.playerLocation == null) return;
        if (WoodenMan.woodenManLocation == null) return;
        if (!running) {
            this.runTaskTimer(WoodenMan.getInstance(), 0, 1);
            this.running = true;
        }
    }

    public void stop() {
        if (running) {
            this.cancel();
            running = false;
        }
        if (woodenMan != null) {
            woodenMan.remove();
            woodenMan = null;
        }
        players.forEach(player -> player.sendMessage(Language.GAME_ENDED));
        players.forEach(this::removePlayer);
        this.gameStage = GameStage.END;
        WoodenMan.gameTask = null;
    }

    public boolean addPlayer(Player player) {
        if (gameStage != GameStage.START) return false;
        if (players.contains(player)) return false;
        return players.add(player);
    }

    public boolean removePlayer(Player player) {
        Location location = playerLocation.get(player);
        if (location != null) {
            player.teleport(location);
        }
        GameMode gameMode = playerGameMode.get(player);
        if (gameMode != null) {
            player.setGameMode(gameMode);
        }
        playerLocation.remove(player);
        playerGameMode.remove(player);
        return players.remove(player);
    }

    // 判断玩家是否在游戏内
    public boolean isPlayerInGame(Player player) {
        return players.contains(player);
    }

    /**
     * 处理玩家与木头人交互的逻辑。
     *
     * @param player 与木头人交互的玩家
     * @param entity 交互实体
     */
    public void handlePlayerInteraction(Player player, Entity entity) {
        if (!players.contains(player)) return;
        if (entity != woodenMan) return;
        gameStage = GameStage.END;
    }

    /**
     * 处理玩家与木头人交互的逻辑。
     *
     * @param player 与木头人交互的玩家
     */
    public void handlePlayerMove(Player player) {
        if (!players.contains(player)) return;
        if (gameStage != GameStage.PLAYING) return;

        if (this.woodenManLookingBack) {
            if (tempReactionTime >= gameTime) {
                this.getMovePlayers().clear(); // 清空 movePlayers 集合
            } else {
                this.getMovePlayers().add(player);
            }
        }
    }

    /**
     * 在指定位置周围获取一个随机位置
     * 
     * @param location 中心位置
     * @param radius 半径范围
     * @return 随机生成的位置
     */
    private Location getRandomLocationAround(Location location, int radius) {
        if (location == null) return null;
        
        World world = location.getWorld();
        if (world == null) return null;
        
        // 生成-radius到radius之间的随机偏移量
        int offsetX = (int) (Math.random() * (2 * radius + 1)) - radius;
        int offsetZ = (int) (Math.random() * (2 * radius + 1)) - radius;
        
        // 创建新的位置，保持Y坐标不变
        return new Location(
            world,
            location.getX() + offsetX,
            location.getY(),
            location.getZ() + offsetZ,
            location.getYaw(),
            location.getPitch()
        );
    }

}
